<template>
  <div>
    <a-input placeholder="请选择"
             :value="valueStr"
             :readOnly="true"
             @click="open" />
    <a-modal title="权限设置"
             width="750px"
             cancelText="取消"
             okText="确定"
             :visible="visible"
             :maskClosable="false"
             :mask="true"
             @ok="handleOk"
             @cancel="handleCancel">
      <div class="box">
        <div class="left">
          <div style="padding:5px">
            <a-input v-model="searchText"
                     @input="searchData"
                     placeholder="搜索" />
            <div v-if="searchText"
                 class="search-list">
              <div v-if="searchList.length > 0"
                   class="list">
                <div :title="item.name"
                     v-for="(item,index) in searchList"
                     :key="index"
                     @click="checkItem(item, $event)">
                  <div>
                    <span>{{ item.name }}</span>
                    <span style="color:#ccc;font-size:12px">{{ item.type == '1' ? ' (机构)' : item.type == '2' ? ' (人员)' : ' (角色)' }}</span>
                  </div>
                </div>
              </div>
              <div v-else
                   class="no-result">
                没有匹配到任何结果
              </div>
            </div>
          </div>
          <TreeData :service="service"
                    v-model="unit"
                    :treeData="unitTree"
                    type="unit"
                    :defaultExpandedKeys="['-1']"
                    @cancel="onCancel"
                    @input="unitInput" />
          <TreeData :service="service"
                    v-model="user"
                    :treeData="userTree"
                    type="user"
                    :defaultExpandedKeys="['-2']"
                    @cancel="onCancel"
                    @input="userInput" />
          <TreeData :service="service"
                    v-model="role"
                    :treeData="roleTree"
                    type="role"
                    :defaultExpandedKeys="['-3']"
                    @cancel="onCancel"
                    @input="roleInput" />
        </div>
        <div class="right">
          <div v-if="checkedData.unitList.length > 0"
               class="right-u size">
            机构
          </div>
          <div class="right-u">
            <a-tag v-for="item in checkedData.unitList"
                   :key="item.key"
                   closable
                   @close="cancel($event,item,'unit')">
              {{ item.name }}
            </a-tag>
          </div>
          <div v-if="checkedData.userList.length > 0"
               class="right-u size">
            人员
          </div>
          <div class="right-u">
            <a-tag v-for="item in checkedData.userList"
                   :key="item.key"
                   closable
                   @close="cancel($event,item,'user')">
              {{ item.name }}
            </a-tag>
          </div>
          <div v-if="checkedData.roleList.length > 0"
               class="right-u size">
            角色
          </div>
          <div class="right-u">
            <a-tag v-for="item in checkedData.roleList"
                   :key="item.key"
                   closable
                   @close="cancel($event,item,'role')">
              {{ item.name }}
            </a-tag>
          </div>
        </div>
      </div>
    </a-modal>
  </div>
</template>

<script>

import _isEmpty from 'lodash/isEmpty'
import _cloneDeep from 'lodash/cloneDeep'
import { findPersion, getTreeUnitUsersByUserIds, getTreeUnitListByUserIds, getRole, member, permission, conditionSearch } from './api.js'
import PropTypes from '@zh/common-utils/prop-types'
import TreeData from './TreeData'
export default {
  name: 'ZUserUnitRoleAuthority',
  components: { TreeData },
  props: {
    service: PropTypes.string.def('application'),
    value: PropTypes.object.def({}),
    applicationId: PropTypes.string.def(''),
    formId: PropTypes.string.def('')
  },
  data () {
    return {
      visible: false,
      activeKey: ['1', '2', '3'],
      unitTree: [],
      userTree: [],
      roleTree: [],
      unit: [],
      user: [],
      role: [],
      checkedData: {
        unitList: [],
        userList: [],
        roleList: []
      },
      levelValue: [],
      valueStr: '',
      searchList: [],
      searchText: '',
      valueCopy: {}
    }
  },

  watch: {
    value: {
      async handler (value) {
        this.valueCopy = _cloneDeep(value)
        this.setValues(value)
      },
      deep: true,
      immediate: true
    }
  },
  mounted () {
    if (this.applicationId) {
      this.getMember()
      return
    }
    if (this.formId) {
      this.getPermission()
      return
    }
    if (!this.applicationId && !this.formId) {
      this.getTreeData()
      return
    }
  },
  methods: {
    async open () {
      this.visible = true
    },
    handleCancel (e) {
      this.setValues(this.valueCopy)
      this.visible = false
    },
    async setValues (value) {
      this.unit = value?.unit || []
      this.user = value?.user || []
      this.role = value?.role || []
      this.checkedData.unitList = await getTreeUnitListByUserIds(this.service, value?.unit || [])
      this.checkedData.userList = await getTreeUnitUsersByUserIds(this.service, value?.user || [])
      this.checkedData.roleList = await getRole(this.service, value?.role || [])
      this.getCheckedData(this.checkedData)
    },
    /** 数据搜索 */
    searchData () {
      this.searchList = []
      if (!this.searchText) {
        return
      }
      let type = true // true为汉字
      const re = /^[0-9a-zA-Z]*$/ // 判断字符串是否为数字和字母组合
      let regex = /^[\u4E00-\u9FA5]+$/ // 判断字符串是否为汉字
      if (re.test(this.searchText)) {
        type = false
      } else if (regex.test(this.searchText)) {
        type = true
      }
      if (!type && this.searchText.length < 2) {
        return
      }
      conditionSearch(this.searchText, this.applicationId, this.formId).then(res => {
        this.searchList = res || []
      })
    },
    checkItem (item) {
      this.searchText = ''
      this.searchList = []
      if (item.type == '1') {
        if (!this.unit.includes(item.id)) {
          this.unit.push(item.id)
          this.unitInput(this.unit)
        }
      } else if (item.type == '2') {
        if (!this.user.includes(item.id)) {
          this.user.push(item.id)
          this.userInput(this.user)
        }
      } else if (item.type == '3') {
        if (!this.role.includes(item.id)) {
          this.role.push(item.id)
          this.roleInput(this.role)
        }
      }
    },
    async handleOk () {
      this.levelValue = await getTreeUnitListByUserIds(this.service, this.unit)
      let { unit, user, role } = this
      this.$emit('input', { unit, user, role }, { unitList: this.checkedData.unitList, userList: this.checkedData.userList, roleList: this.checkedData.roleList })
      this.$emit('change', { unit, user, role }, { unitList: this.checkedData.unitList, userList: this.checkedData.userList, roleList: this.checkedData.roleList })
      this.getCheckedData(this.checkedData)
      this.visible = false
    },
    getCheckedData (checkedData) {
      let str = []
      for (let key in checkedData) {
        checkedData[key].map(it => {
          it.name && str.push(it.name)
        })
      }
      this.valueStr = str.join(',')
    },
    async unitInput (value) {
      value && (this.checkedData.unitList = await getTreeUnitListByUserIds(this.service, value))
    },
    async userInput (value) {
      value && (this.checkedData.userList = await getTreeUnitUsersByUserIds(this.service, value))
    },
    async roleInput (value) {
      value && (this.checkedData.roleList = await getRole(this.service, value))
    },
    getPermission () {
      permission(this.formId).then(res => {
        let data = {
          unit: res[2],
          user: res[1],
          role: res[3]
        }
        this.createTree(data)
      })
    },
    getMember () {
      member(this.applicationId).then(res => {
        this.createTree(res)
      })
    },
    createTree (res) {
      // 组装成一棵树结构
      res?.unit && getTreeUnitListByUserIds(this.service, res.unit).then(res => {
        this.unitTree = [{
          id: '-1',
          key: '-1',
          name: '机构',
          disabled: false,
          children: res.map(item => {
            item.key = item.id
            return item
          })
        }]
      })
      res?.user && getTreeUnitUsersByUserIds(this.service, res.user).then(res => {
        this.userTree = [{
          id: '-2',
          key: '-2',
          name: '人员',
          disabled: false,
          children: res.map(item => {
            item.key = item.id
            return item
          })
        }]
      })
      res?.role && getRole(this.service, res.role).then(res => {
        this.roleTree = [{
          id: '-3',
          key: '-3',
          name: '角色',
          disabled: false,
          children: res.map(item => {
            item.key = item.id
            item.isLeaf = true
            return item
          })
        }]
      })
    },
    getInitTreeData () {
      return new Promise((resolve) => {
        findPersion(this.service).then((response) => {
          resolve(response)
        })
      })
    },
    getTreeData () {
      if (this.getInitTreeData) {
        this.getInitTreeData().then((res) => {
          res.map(item => {
            item.disabled = false
            item.checkable = false
          })
          res[1].children.map(item => {
            item.checkable = false
          })
          this.unitTree = [res[0]]
          this.userTree = [res[1]]
          this.roleTree = [res[2]]
        })
      }
    },
    onCancel ({ type, item }) {
      this.cancel(null, item, type)
    },
    cancel (e, item, type) {
      e && e.preventDefault()
      if (type == 'unit') {
        const index = this.unit.indexOf(item.id)
        if (index > -1) {
          this.unit.splice(this.unit.indexOf(item.id), 1)
          this.unitInput(this.unit)
        }
      } else if (type == 'user') {
        const index = this.user.indexOf(item.id)
        if (index > -1) {
          this.user.splice(this.user.indexOf(item.id), 1)
          this.userInput(this.user)
        }
      } else if (type == 'role') {
        const index = this.role.indexOf(item.id)
        if (index > -1) {
          this.role.splice(index, 1)
          this.roleInput(this.role)
        }
      }
    }
  }
}
</script>

<style lang="less" scoped >
/deep/.ant-tag {
  margin-bottom: 5px;
}
/deep/.ant-collapse {
  border: none;
}
/deep/.ant-modal-body {
  padding: 0px;
}
/deep/.ant-tree-checkbox-disabled {
  display: none;
}
.box {
  width: 100%;
  display: flex;
  // border: 1px solid #ccc;
  .left {
    width: 49%;
    overflow: auto;
    height: 450px;
    .search-list {
      top: 95px;
      position: absolute;
      background-color: #fff;
      z-index: 9999;
      width: 284px;
      min-height: 70px;
      max-height: 300px;
      overflow-y: auto;
      box-shadow: 0 0 5px #ddd;
      border-radius: 5px;
      border: 1px solid #ccc;
      .list {
        // padding: 10px 0;
        & > div {
          padding: 0 20px;
          height: 40px;
          line-height: 40px;
          border-bottom: 1px solid #eee;
          white-space: nowrap;
          text-overflow: ellipsis;
          overflow: hidden;
          word-break: break-all;
          cursor: pointer;
          &:hover {
            background-color: #f5f5f5;
          }
          i {
            display: inline-block;
            margin-right: 5px;
          }
        }
        & > div:last-child {
          border-bottom: none;
        }
        & > div:first-child {
          border-bottom: 1px solid #eee;
        }
      }
      .no-result {
        text-align: center;
        line-height: 70px;
        font-size: var(--font-size-18);
        color: #999;
      }
    }
  }
  .right {
    flex: 1;
    overflow: auto;
    height: 450px;
    border-left: 1px solid #ccc;
    .right-u {
      padding: 5px;
    }
    .size {
      font-size: 16px;
      font-weight: bold;
    }
  }
}
</style>
